package com.ruoyi.common.banbeiPay;

import com.ruoyi.common.constant.Constants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 *
 */
public class MyBeanUtils extends BeanUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyBeanUtils.class);

    private MyBeanUtils(){ }

    public static Map convertBean(Object bean, Map retMap)
            throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        Class clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
        }
        for (Field f : fields) {
            String key = f.toString().substring(f.toString().lastIndexOf(".") + 1);
            if (StringUtils.equalsIgnoreCase("NEED_SIGN_PARAMS", key)
                    || StringUtils.equalsIgnoreCase("serialVersionUID", key)) {
                continue;
            }
            Object value = f.get(bean);
            if (value == null) {
                value = "";
            }
            retMap.put(key, value);
        }
        return retMap;
    }

    public static String getSigned(Map<String, String> map, String[] excludes, boolean isCommon){
        StringBuffer sb = new StringBuffer();
        Set<String> excludeSet = new HashSet<String>();
        excludeSet.add("sign");
        if(excludes != null){
            for(String exclude : excludes){
                excludeSet.add(exclude);
            }
        }
        for(String key : map.keySet()){
            if(!excludeSet.contains(key)){
                String value = map.get(key);
                value = (value == null ? "" : value);
                sb.append(Constants.SPLIT);
                sb.append(value);
            }
        }
        sb.append(Constants.SPLIT);
        String key = Constants.SIGNKEY_MD5;
        if (isCommon){
            key = Constants.COMMON_MD5;
        }
        sb.append(key);
        return sb.toString();
    }

    public static String getSigned(Object bean, String[] excludes,boolean isCommon) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        Map map  = convertBean(bean, new LinkedHashMap());
        String signedStr = getSigned(map, excludes,isCommon);
        return signedStr;
    }

    /**
     * new style
     *
     * @param bean
     * @param needSignParams
     */
    public static String getSignedByPresetParameter(Object bean, Set<String> needSignParams, boolean isCommon) throws IllegalAccessException,
            IntrospectionException, InvocationTargetException {
        Map map = convertBean(bean, new LinkedHashMap<>());
        return getSignedByPresetParameter(map, needSignParams,isCommon);
    }

    /**
     * new style
     *
     * @param map
     * @param needSignParams
     * @return
     */
    public static String getSignedByPresetParameter(Map<String, String> map, Set<String> needSignParams, boolean isCommon) {
        StringBuffer sb = new StringBuffer();
        if (needSignParams == null || needSignParams.isEmpty()) {
            throw new RuntimeException("needSignParams is required");
        }
        for (String key : map.keySet()) {
            if (needSignParams.contains(key)) {
                // do sign
                String value = map.get(key);
                value = (value == null ? "" : value);
                sb.append(Constants.SPLIT);
                sb.append(value);
            }
        }
        String key = Constants.SIGNKEY_MD5;
        if (isCommon){
            key = Constants.COMMON_MD5;
        }
        sb.append(Constants.SPLIT).append(key);
        LOGGER.info("sign result:{}", sb.toString());
        return sb.toString();
    }

}
